{% extends "base.html" %}
{% block header-content %}
<h3>Welcome</h3>
<p>Welcome to the appengine-utilities project demo site. appengine-utilities is a collection of utilities designed to reduce the amount of time required to build applications on top of the Google AppEngine environment. It includes:</p>
<p>
<ul>
    <li><strong>sessions: </strong>A complete sessions management class that uses both the datastore and memcache to provide a high performance library while maintaining reliability.</li>
    <li><strong>cache: </strong>A simple to use caching system that utilizes both the datastore and memcache for storage.</li>
    <li><strong>flash: </strong>A cookie based messaging utility. Set a flash message to be displayed on the next request made by the user. This is also integrated into sessions.</li>
    <li><strong>event: </strong>A subscribe/fire event system. Events are included in sessions and cache which can be hooked into using this class.</li>
    <li><strong>ROTModel: </strong>An extension of Google's db.Model that automatically retries put operations when db.Timeout is encountered.</li>
</ul>
</p>
{% endblock %}
{% block content %}
        <h2>Recent Updates</h2>
        <p><strong>[10/26/2008]</strong>Project renamed to gaeutilities. 1.0 release.</p>
        <p><strong>[1/19/2009]</strong>1.1.1 Release, including new ROTModel</p>
        <p><strong>[1/26/2009]</strong>1.1.2 Release<br />
   	 - session: Added last_activity_update variable to set an interval for which last_activity needs to be updated. It defaults to 60 seconds. This means a put is not 
required every request which should increase performance.<br />
 - session: Refactored based on a contribution from Jeremy Awon optimizing the class initialization.<br />
 - session: Bug found in the process to clear old sessions that was deleting data it shouldn't be. This was the cause of the mysterious missing session data bug. Thank you 
pant.lalit<br />
 - session: Bug fixed where clean_check_percent was being ignored.<br />
 - session: Some tweaks done to delete_all_session(), though this feature shouldn't be considered complete yet. Needs more testing.<br />
</p>
<p><strong>[2/8/2009]</strong>1.1.3 Release<br />
 - session: bugfix to handle str() and len() methods when there is no session data. Issue #12<br />
 - session: delete_all_sessions changed to a class method. Issue #14 (NOTE: delete_all_sessions is not complete)<br />
 - session: Modified session token to include the session key. Issue #10<br />
 - session: Session token encryption changed to md5 from sha1, in order to improve performance as the salt is randomized with a time string.<br />
 </p>
 <p><strong>[2/20/2009]</strong>1.2 Release<br />
  - Bugfix: session deleting was failing and making it so that an error
  would be presented on every pageview until cookies were cleared. This is
  fixed.
  - sessions.py - Cookie sessions are now in.<br/>
  You can now initialize session as Session(writer="cookie") and all
  session values will be stored in a new cookie within the browser,
  bypassing the datastore altogether. If you are creating an application that
  does not need to protect the session data, this will have huge CPU
  benefits. Another user is to initialize cookie writer sessions for your
  application's non-logged in users. When the user logs in you can reset the
  session to the normal datastore backed one. <br />
  A new class method check_token() has been created to determine which type of
  session is available to the user. Session.check_token() will check to see if a
  session token cookie exists in the users browser, then will determine if it's
  valid or not. Thus check_token allows you to do something like:<br />
  <pre>
  if Session.check_token():
      session = Session()
  else:
      session = Session(writer="cookie")
  </pre>
  The django middleware has been updated to use this. However, this does mean
  you have an extra level of management necessary for your login
  functionality for django now. This has only been tested on appenginepatch with
  the latest django.
  For example to log in a user you'd want to do something like this:
  <pre>
        user = auth.authenticate(account = id)
        if user is not None and user.is_active:
            request.session.save()
            auth.login(request, user)
  </pre>

 </p>

 {% endblock %}
